package com.chen10.cattle.ai;

import com.chen10.cattle.ai.model.Position;
import lombok.Data;

import java.util.ArrayList;
import java.util.Arrays;

@Data
public class Chess {
    private int size;//棋盘大小
    private int[][] chessboard;//棋盘
    private int color= 1;//1为黑子，2为白子
    /*
     * 以所选位置为中心的各种棋型，有连5，活4，眠4，活3，眠3，活2，眠2;
     * 连5:1111,2222;
     * 活4:1110,0111,2220,0222;
     * 眠4:1112,2111,2221,1222;
     * 活3:1100,0011,0110,2200,0022,0220;
     * 眠3:1120,1121,0211,1211,2110,0112,2210,2211,0122,2122,1220,0221;
     * 活2:0100,0010,0200,0020;
     * 眠2:2100,0012,1200,0021;
     */
    private int[][] stiuation = {{1, 1, 1, 1}, {2, 2, 2, 2}, {1, 1, 1, 0}, {0, 1, 1, 1}, {2, 2, 2, 0},
            {0, 2, 2, 2}, {1, 1, 1, 2}, {2, 1, 1, 1}, {2, 2, 2, 1}, {1, 2, 2, 2}, {1, 1, 0, 0},
            {0, 0, 1, 1}, {0, 1, 1, 0}, {2, 2, 0, 0}, {0, 0, 2, 2}, {0, 2, 2, 0}, {1, 1, 2, 0},
            {1, 1, 2, 1}, {0, 2, 1, 1}, {1, 2, 1, 1}, {2, 1, 1, 0}, {0, 1, 1, 2}, {2, 2, 1, 0},
            {2, 2, 1, 1}, {0, 1, 2, 2}, {2, 1, 2, 2}, {1, 2, 2, 0}, {0, 2, 2, 1}, {0, 1, 0, 0},
            {0, 0, 1, 0}, {0, 2, 0, 0}, {0, 0, 2, 0}, {2, 1, 0, 0}, {0, 0, 1, 2}, {1, 2, 0, 0},

    };
    /*
     * 以所选位置为起点的棋型，连5，活4，眠4，活3，眠3;
     * 连5:1111,2222;
     * 活4:1110,2220;
     * 眠4:1112,2221;
     * 活3:1100,1101,1102,2200,2201,2202;
     * 眠3:1120,1121,1122,2210,2211,2122;
     */
    private int[][] stiuation2 = {{1, 1, 1, 1}, {2, 2, 2, 2}, {1, 1, 1, 0}, {2, 2, 2, 0}, {1, 1, 1, 2},
            {2, 2, 2, 1}, {1, 1, 0, 0}, {1, 1, 0, 1}, {1, 1, 0, 2}, {2, 2, 0, 0}, {2, 2, 0, 1},
            {2, 2, 0, 2}, {1, 1, 2, 0}, {1, 1, 2, 1}, {1, 1, 2, 2}, {2, 2, 1, 0}, {2, 2, 1, 1},
            {2, 2, 1, 2}
    };

    //下棋，x和y分别是人下棋的横坐标和纵坐标，电脑根据坐标来判断下棋位置下棋
    public Position getMove(int x,int y) {

        //存储所有未下棋的位置
        ArrayList<Position> positions=new ArrayList<>();
        //存储每个位置的评分
        ArrayList<Integer> numbers=new ArrayList<>();

        for (int i = 0; i < chessboard.length; i++) {
            for (int j = 0; j < chessboard.length; j++) {
                positions.add(new Position(i,j));
                numbers.add(numJudge(i,j));
            }
        }
        int index = 0;// 最高评分在numbers中的下标
        for (int i = 0; i < numbers.size(); i++) {
            if (numbers.get(i) > numbers.get(index)) {
                index = i;
            }
        }
        // 储存所有最高评分在numbers中的下标(当最高评分有多个时)
        ArrayList<Integer> max = new ArrayList<>();
        for (int i = 0; i < numbers.size(); i++) {
            if (numbers.get(i) == numbers.get(index)) {
                max.add(i);
            }
        }
        System.out.println("电脑下棋：("+positions.get(max.get(0)).getRow()+","+positions.get(max.get(0)).getCol()+")");
        return new Position(positions.get(max.get(0)).getRow(),positions.get(max.get(0)).getCol());
    }

    //评分算法
    private int numJudge(int x, int y) {
        int sum = 0;
        sum += mark1(x, y);// 左右方向
        sum += mark2(x, y);// 上下方向
        sum += mark3(x, y);// 主对角线方向
        sum += mark4(x, y);// 副对角线方向
        sum += mark5(x, y);// 八个方向
        return sum;
    }

    // 给分标准1,根据棋型给分
    private int calculate(int[] position) {
        int sum = 0;
        int index = -1;
        for (int i = 0; i < this.stiuation.length; i++) {
            if (Arrays.equals(position, this.stiuation[i])) {
                index = i;
                if (i < 2) {
                    sum += 100000;// 连5棋型
                    if (color == 1) {
                        if (i == 0) {
                            sum += 10000000;// 我方胜利加分
                        }
                    } else {
                        if (i == 1) {
                            sum += 10000000;// 我方胜利加分
                        }
                    }
                } else if (i < 6) {
                    sum += 10000;// 活4棋型
                    if (color == 1) {
                        if (i <= 3) {
                            sum += 50000;//我方先连4子加分
                        }
                    } else {
                        if (i > 3) {
                            sum += 50000;//我方先连4子加分
                        }
                    }
                } else if (i < 10) {
                    sum += 5000;// 眠4棋型
                } else if (i < 16) {
                    sum += 1000;// 活3棋型
                    if (color == 1) {
                        if (i <= 12) {
                            sum += 3000;//我方先连3子加分
                        }
                    } else {
                        if (i > 12) {
                            sum += 3000;//我方先连3子加分
                        }
                    }
                } else if (i < 28) {
                    sum += 500;// 眠3棋型
                } else if (i < 32) {
                    sum += 100;// 活2棋型
                } else {
                    sum += 50;// 眠2棋型
                }
            }
        }
        if (index < 0) {
            sum += 1;// 其它情况
        }
        return sum;
    }

    // 评分标准2
    private int calculate2(int[] position) {
        int sum = 0;
        for (int i = 0; i < this.stiuation2.length; i++) {
            if (Arrays.equals(position, this.stiuation2[i])) {
                if (i < 2) {

                    sum += 100000;// 连5棋型
                    if (color == 1) {
                        if (i == 0) {
                            sum += 10000000;// 一子定胜负加分
                        }
                    } else {
                        if (i == 1) {
                            sum += 10000000;// 一子定胜负加分
                        }
                    }
                } else if (i < 4) {
                    sum += 10000;// 活4棋型
                    if (color == 1) {
                        if (i == 2) {
                            sum += 50000;//我方先连4子加分
                        }
                    } else {
                        if (i == 3) {
                            sum += 50000;//我方先连4子加分
                        }
                    }
                } else if (i < 6) {
                    sum += 5000;// 眠4棋型
                } else if (i < 12) {
                    sum += 1000;// 活3棋型
                    if (color == 1) {
                        if (i <= 8) {
                            sum += 3000;//我方先连3子加分
                        }
                    } else {
                        if (i > 8) {
                            sum += 3000;//我方先连3子加分
                        }
                    }
                } else {
                    sum += 500;// 眠3棋型
                }
            }
        }
        return sum;
    }

    // 左右方向评分
    private int mark1(int x, int y) {
        int[] position = new int[4];
        if (x - 2 >= 0) {
            position[0] = this.chessboard[x - 2][y];
        } else {
            position[0] = 0;
        }
        if (x - 1 >= 0) {
            position[1] = this.chessboard[x - 1][y];
        } else {
            position[1] = 0;
        }
        if (x + 1 < this.chessboard.length) {
            position[2] = this.chessboard[x + 1][y];
        } else {
            position[2] = 0;
        }
        if (x + 2 < this.chessboard.length) {
            position[3] = this.chessboard[x + 2][y];
        } else {
            position[3] = 0;
        }
        int sum = 0;
        sum += calculate(position);
        return sum;
    }

    // 上下方向评分
    private int mark2(int x, int y) {
        int[] position = new int[4];
        if (y - 2 >= 0) {
            position[0] = this.chessboard[x][y - 2];
        } else {
            position[0] = 0;
        }
        if (y - 1 >= 0) {
            position[1] = this.chessboard[x][y - 1];
        } else {
            position[1] = 0;
        }
        if (y + 1 < this.chessboard.length) {
            position[2] = this.chessboard[x][y + 1];
        } else {
            position[2] = 0;
        }
        if (y + 2 < this.chessboard.length) {
            position[3] = this.chessboard[x][y + 2];
        } else {
            position[3] = 0;
        }
        int sum = 0;
        sum += calculate(position);
        return sum;
    }

    // 主对角线方向评分
    private int mark3(int x, int y) {
        int[] position = new int[4];
        if (x - 2 >= 0 && y - 2 >= 0) {
            position[0] = this.chessboard[x - 2][y - 2];
        } else {
            position[0] = 0;
        }
        if (x - 1 >= 0 && y - 1 >= 0) {
            position[1] = this.chessboard[x - 1][y - 1];
        } else {
            position[1] = 0;
        }
        if (x + 1 < this.chessboard.length && y + 1 < this.chessboard.length) {
            position[2] = this.chessboard[x + 1][y + 1];
        } else {
            position[2] = 0;
        }
        if (x + 2 < this.chessboard.length && y + 2 < this.chessboard.length) {
            position[3] = this.chessboard[x + 2][y + 2];
        } else {
            position[3] = 0;
        }
        int sum = 0;
        sum += calculate(position);
        return sum;
    }

    // 副对角线方向评分
    private int mark4(int x, int y) {
        int[] position = new int[4];
        if (x - 2 >= 0 && y + 2 < this.chessboard.length) {
            position[0] = this.chessboard[x - 2][y + 2];
        } else {
            position[0] = 0;
        }
        if (x - 1 >= 0 && y + 1 < this.chessboard.length) {
            position[1] = this.chessboard[x - 1][y + 1];
        } else {
            position[1] = 0;
        }
        if (x + 1 < this.chessboard.length && y - 1 >= 0) {
            position[2] = this.chessboard[x + 1][y - 1];
        } else {
            position[2] = 0;
        }
        if (x + 2 < this.chessboard.length && y - 2 >= 0) {
            position[3] = this.chessboard[x + 2][y - 2];
        } else {
            position[3] = 0;
        }
        int sum = 0;
        sum += calculate(position);
        return sum;
    }


    // 八个方向评分
    private int mark5(int x, int y) {
        int sum = 0;
        int[] position = new int[4];
        // 上方向
        if (x - 1 >= 0) {
            position[0] = this.chessboard[x - 1][y];
        } else {
            position[0] = 0;
        }
        if (x - 2 >= 0) {
            position[1] = this.chessboard[x - 2][y];
        } else {
            position[1] = 0;
        }
        if (x - 3 >= 0) {
            position[2] = this.chessboard[x - 3][y];
        } else {
            position[2] = 0;
        }
        if (x - 4 >= 0) {
            position[3] = this.chessboard[x - 4][y];
        } else {
            position[3] = 0;
        }
        sum += calculate2(position);
        // 下方向
        if (x + 1 < this.chessboard.length) {
            position[0] = this.chessboard[x + 1][y];
        } else {
            position[0] = 0;
        }
        if (x + 2 < this.chessboard.length) {
            position[1] = this.chessboard[x + 2][y];
        } else {
            position[1] = 0;
        }
        if (x + 3 < this.chessboard.length) {
            position[2] = this.chessboard[x + 3][y];
        } else {
            position[2] = 0;
        }
        if (x + 4 < this.chessboard.length) {
            position[3] = this.chessboard[x + 4][y];
        } else {
            position[3] = 0;
        }
        sum += calculate2(position);
        // 左方向
        if (y - 1 >= 0) {
            position[0] = this.chessboard[x][y - 1];
        } else {
            position[0] = 0;
        }
        if (y - 2 >= 0) {
            position[1] = this.chessboard[x][y - 2];
        } else {
            position[1] = 0;
        }
        if (y - 3 >= 0) {
            position[2] = this.chessboard[x][y - 3];
        } else {
            position[2] = 0;
        }
        if (y - 4 >= 0) {
            position[3] = this.chessboard[x][y - 4];
        } else {
            position[3] = 0;
        }
        sum += calculate2(position);
        // 右方向
        if (y + 1 < this.chessboard.length) {
            position[0] = this.chessboard[x][y + 1];
        } else {
            position[0] = 0;
        }
        if (y + 2 < this.chessboard.length) {
            position[1] = this.chessboard[x][y + 2];
        } else {
            position[1] = 0;
        }
        if (y + 3 < this.chessboard.length) {
            position[2] = this.chessboard[x][y + 3];
        } else {
            position[2] = 0;
        }
        if (y + 4 < this.chessboard.length) {
            position[3] = this.chessboard[x][y + 4];
        } else {
            position[3] = 0;
        }
        sum += calculate2(position);
        // 左斜上方向
        if (x - 1 >= 0 && y - 1 >= 0) {
            position[0] = this.chessboard[x - 1][y - 1];
        } else {
            position[0] = 0;
        }
        if (x - 2 >= 0 && y - 2 >= 0) {
            position[1] = this.chessboard[x - 2][y - 2];
        } else {
            position[1] = 0;
        }
        if (x - 3 >= 0 && y - 3 >= 0) {
            position[2] = this.chessboard[x - 3][y - 3];
        } else {
            position[2] = 0;
        }
        if (x - 4 >= 0 && y - 4 >= 0) {
            position[3] = this.chessboard[x - 4][y - 4];
        } else {
            position[3] = 0;
        }
        sum += calculate2(position);
        // 左斜下方向
        if (x + 1 < this.chessboard.length && y + 1 < this.chessboard.length) {
            position[0] = this.chessboard[x + 1][y + 1];
        } else {
            position[0] = 0;
        }
        if (x + 2 < this.chessboard.length && y + 2 < this.chessboard.length) {
            position[1] = this.chessboard[x + 2][y + 2];
        } else {
            position[1] = 0;
        }
        if (x + 3 < this.chessboard.length && y + 3 < this.chessboard.length) {
            position[2] = this.chessboard[x + 3][y + 3];
        } else {
            position[2] = 0;
        }
        if (x + 4 < this.chessboard.length && y + 4 < this.chessboard.length) {
            position[3] = this.chessboard[x + 4][y + 4];
        } else {
            position[3] = 0;
        }
        sum += calculate2(position);
        // 右斜上方向
        if (x - 1 >= 0 && y + 1 < this.chessboard.length) {
            position[0] = this.chessboard[x - 1][y + 1];
        } else {
            position[0] = 0;
        }
        if (x - 2 >= 0 && y + 2 < this.chessboard.length) {
            position[1] = this.chessboard[x - 2][y + 2];
        } else {
            position[1] = 0;
        }
        if (x - 3 >= 0 && y + 3 < this.chessboard.length) {
            position[2] = this.chessboard[x - 3][y + 3];
        } else {
            position[2] = 0;
        }
        if (x - 4 >= 0 && y + 4 < this.chessboard.length) {
            position[3] = this.chessboard[x - 4][y + 4];
        } else {
            position[3] = 0;
        }
        sum += calculate2(position);
        // 右斜下
        if (x + 1 < this.chessboard.length && y - 1 >= 0) {
            position[0] = this.chessboard[x + 1][y - 1];
        } else {
            position[0] = 0;
        }
        if (x + 2 < this.chessboard.length && y - 2 >= 0) {
            position[1] = this.chessboard[x + 2][y - 2];
        } else {
            position[1] = 0;
        }
        if (x + 3 < this.chessboard.length && y - 3 >= 0) {
            position[2] = this.chessboard[x + 3][y - 3];
        } else {
            position[2] = 0;
        }
        if (x + 4 < this.chessboard.length && y - 4 >= 0) {
            position[3] = this.chessboard[x + 4][y - 4];
        } else {
            position[3] = 0;
        }
        sum += calculate2(position);
        return sum;
    }

}
